import datetime
import logging
import traceback

from flask import request, jsonify, g
from flask_jwt_extended import jwt_required, get_jwt_identity, get_jwt
from werkzeug.security import generate_password_hash
from app.models import Admin, Tenant, Role, AdminLog, User, TenantConfigService
from app.core.extensions import db
from app.models.tenant_config import ConfigTypes
from app.services.tenant_config_service import DynamicTenantConfig
from . import admin_blueprint


@admin_blueprint.route('/tenants', methods=['GET'])
@jwt_required()
def get_tenants():
    """获取租户列表"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)

    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404

    # 只有超级管理员可以查看所有租户
    if not admin.is_super:
        return jsonify({'code': 1, 'message': '只有超级管理员可以查看租户列表'}), 403

    # 获取请求参数
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 10, type=int)
    name = request.args.get('name', '')
    status = request.args.get('status', '')

    # 构建查询
    query = Tenant.query

    # 应用过滤条件
    if name:
        query = query.filter(Tenant.name.like(f'%{name}%'))
    if status:
        query = query.filter(Tenant.status == status)

    # 分页查询
    pagination = query.order_by(Tenant.id.desc()).paginate(page=page, per_page=limit, error_out=False)

    # 构建响应数据
    result = {
        'items': [tenant.to_dict() for tenant in pagination.items],
        'total': pagination.total
    }

    return jsonify({'code': 0, 'message': '获取成功', 'data': result})


@admin_blueprint.route('/tenants/<int:tenant_id>', methods=['GET'])
@jwt_required()
def get_tenant(tenant_id):
    """获取租户详情"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)

    if not admin:
        return jsonify({'code': 1, 'message': '管理员不存在'}), 404

    # 只有超级管理员可以查看租户详情
    if not admin.is_super:
        return jsonify({'code': 1, 'message': '只有超级管理员可以查看租户详情'}), 403

    tenant = Tenant.query.get(tenant_id)
    if not tenant:
        return jsonify({'code': 1, 'message': '租户不存在'}), 404

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': tenant.to_dict()
    })


@admin_blueprint.route('/tenants', methods=['POST'])
@jwt_required()
def create_tenant():
    """创建租户"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    claims = get_jwt()

    # 测试账号不能创建租户
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能创建租户'}), 403

    # 只有超级管理员可以创建租户
    if not admin.is_super:
        return jsonify({'code': 1, 'message': '只有超级管理员可以创建租户'}), 403

    data = request.json
    name = data.get('name')
    code = data.get('code')
    app_id = data.get('app_id')
    admin_name = data.get('admin_name')
    status = data.get('status', 'active')
    expire_date_str = data.get('expire_date')
    remark = data.get('remark', '')

    if not name or not code or not app_id or not admin_name:
        return jsonify({'code': 1, 'message': '租户名称、标识、AppID、管理员账号不能为空'}), 400

    # 检查租户标识是否已存在
    existing_tenant = Tenant.query.filter_by(code=code).first()
    if existing_tenant:
        return jsonify({'code': 1, 'message': '租户标识已存在'}), 400

    # 检查AppID是否已存在
    existing_app_id = Tenant.query.filter_by(app_id=app_id).first()
    if existing_app_id:
        return jsonify({'code': 1, 'message': 'AppID已存在'}), 400

    # 检查管理员账号是否已存在
    existing_admin = Admin.query.filter_by(username=admin_name).first()
    if existing_admin:
        return jsonify({'code': 1, 'message': '管理员账号已存在'}), 400

    # 解析过期日期
    expire_date = None
    if expire_date_str:
        try:
            expire_date = datetime.datetime.strptime(expire_date_str, '%Y-%m-%d').date()
        except ValueError:
            return jsonify({'code': 1, 'message': '日期格式不正确，应为YYYY-MM-DD'}), 400

    try:
        from app.core.tenant_utils import skip_tenant_auto_set

        # 创建新租户（跳过自动设置租户ID）
        with skip_tenant_auto_set():
            tenant = Tenant(
                name=name,
                code=code,
                app_id=app_id,
                admin_name=admin_name,
                status=status,
                expire_date=expire_date,
                remark=remark
            )
            db.session.add(tenant)
            db.session.flush()  # 获取租户ID

        # 创建租户管理员账号（默认密码为123456）
        from app.utils.password import generate_password_hash
        default_password = "123456"  # 默认密码
        tenant_admin = Admin(
            username=admin_name,
            password_hash=default_password,
            is_super=False,
            is_test=False,
            tenant_id=tenant.id
        )
        tenant_admin.create_time = datetime.datetime.now()
        db.session.add(tenant_admin)

        # 创建基础角色
        admin_role = Role(
            name='管理员',
            description='租户管理员角色',
            tenant_id=tenant.id
        )
        db.session.add(admin_role)
        db.session.flush()

        # 将角色分配给管理员
        tenant_admin.roles.append(admin_role)

        # 记录操作日志
        log = AdminLog(
            admin_id=admin.id,
            action='创建租户',
            ip=request.remote_addr,
            details=f'创建租户 {name}'
        )
        db.session.add(log)

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': '创建成功',
            'data': {
                'id': tenant.id,
                'admin_username': admin_name,
                'admin_password': default_password,
                'message': '管理员账号已创建，默认密码为123456，请及时修改'
            }
        })

    except Exception as e:
        db.session.rollback()
        logging.error("".join(traceback.format_exc()))
        return jsonify({'code': 1, 'message': f'创建失败: {str(e)}'}), 500


@admin_blueprint.route('/tenants/<int:tenant_id>', methods=['PUT'])
@jwt_required()
def update_tenant(tenant_id):
    """更新租户"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    claims = get_jwt()

    # 测试账号不能更新租户
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能更新租户'}), 403

    # 只有超级管理员可以更新租户
    if not admin.is_super:
        return jsonify({'code': 1, 'message': '只有超级管理员可以更新租户'}), 403

    tenant = Tenant.query.get(tenant_id)
    if not tenant:
        return jsonify({'code': 1, 'message': '租户不存在'}), 404

    data = request.json
    name = data.get('name')
    code = data.get('code')
    app_id = data.get('app_id')
    admin_name = data.get('admin_name')
    status = data.get('status')
    expire_date_str = data.get('expire_date')
    remark = data.get('remark')

    if not name or not code or not app_id or not admin_name:
        return jsonify({'code': 1, 'message': '租户名称、标识、AppID和管理员账号不能为空'}), 400

    # 检查租户标识是否已存在（排除自身）
    existing_tenant = Tenant.query.filter(Tenant.code == code, Tenant.id != tenant_id).first()
    if existing_tenant:
        return jsonify({'code': 1, 'message': '租户标识已存在'}), 400

    # 检查AppID是否已存在（排除自身）
    existing_app_id = Tenant.query.filter(Tenant.app_id == app_id, Tenant.id != tenant_id).first()
    if existing_app_id:
        return jsonify({'code': 1, 'message': 'AppID已存在'}), 400

    # 解析过期日期
    expire_date = None
    if expire_date_str:
        try:
            expire_date = datetime.datetime.strptime(expire_date_str, '%Y-%m-%d').date()
        except ValueError:
            return jsonify({'code': 1, 'message': '日期格式不正确，应为YYYY-MM-DD'}), 400

    try:
        # 更新租户信息
        tenant.name = name
        tenant.code = code
        tenant.app_id = app_id
        tenant.admin_name = admin_name
        if status:
            tenant.status = status
        if expire_date:
            tenant.expire_date = expire_date
        if remark is not None:
            tenant.remark = remark
        tenant.updated_at = datetime.datetime.now()

        # 记录操作日志
        log = AdminLog(
            admin_id=admin.id,
            action='更新租户',
            ip=request.remote_addr,
            details=f'更新租户 {name}'
        )
        db.session.add(log)

        db.session.commit()

        return jsonify({'code': 0, 'message': '更新成功'})

    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'message': f'更新失败: {str(e)}'}), 500


@admin_blueprint.route('/tenants/<int:tenant_id>/status', methods=['PUT'])
@jwt_required()
def update_tenant_status(tenant_id):
    """更新租户状态"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    claims = get_jwt()

    # 测试账号不能更新租户状态
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能更新租户状态'}), 403

    # 只有超级管理员可以更新租户状态
    if not admin.is_super:
        return jsonify({'code': 1, 'message': '只有超级管理员可以更新租户状态'}), 403

    tenant = Tenant.query.get(tenant_id)
    if not tenant:
        return jsonify({'code': 1, 'message': '租户不存在'}), 404

    data = request.json
    status = data.get('status')

    if not status:
        return jsonify({'code': 1, 'message': '状态不能为空'}), 400

    try:
        # 更新租户状态
        old_status = tenant.status
        tenant.status = status

        # 记录操作日志
        log = AdminLog(
            admin_id=admin.id,
            action='更新租户状态',
            ip=request.remote_addr,
            details=f'更新租户 {tenant.name} 状态从 {old_status} 到 {status}'
        )
        db.session.add(log)

        db.session.commit()

        return jsonify({'code': 0, 'message': '更新成功'})

    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'message': f'更新失败: {str(e)}'}), 500


@admin_blueprint.route('/tenants/<int:tenant_id>', methods=['DELETE'])
@jwt_required()
def delete_tenant(tenant_id):
    """删除租户"""
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)
    claims = get_jwt()

    # 测试账号不能删除租户
    if claims.get('is_test'):
        return jsonify({'code': 1, 'message': '测试账号不能删除租户'}), 403

    # 只有超级管理员可以删除租户
    if not admin.is_super:
        return jsonify({'code': 1, 'message': '只有超级管理员可以删除租户'}), 403

    tenant = Tenant.query.get(tenant_id)
    if not tenant:
        return jsonify({'code': 1, 'message': '租户不存在'}), 404

    # 不能删除默认租户（ID为1）
    if tenant_id == 1:
        return jsonify({'code': 1, 'message': '不能删除默认租户'}), 400

    # 检查租户下是否有数据，给出警告
    admin_count = Admin.query.filter_by(tenant_id=tenant_id).count()

    try:
        # 记录操作日志
        log = AdminLog(
            admin_id=admin.id,
            action='删除租户',
            ip=request.remote_addr,
            details=f'删除租户 {tenant.name}'
        )
        db.session.add(log)

        # 4. 删除租户下的管理员
        Admin.query.filter_by(tenant_id=tenant_id).delete()

        # 5. 删除其他相关数据
        # 删除租户配置
        from app.models.tenant_config import TenantConfig
        TenantConfig.query.filter_by(tenant_id=tenant_id).delete()

        # 删除租户相关的系统数据
        from app.models.system import Banner, Notice, Article, SystemLog, Feedback, Menu
        Banner.query.filter_by(tenant_id=tenant_id).delete()
        Notice.query.filter_by(tenant_id=tenant_id).delete()
        Article.query.filter_by(tenant_id=tenant_id).delete()
        SystemLog.query.filter_by(tenant_id=tenant_id).delete()
        Feedback.query.filter_by(tenant_id=tenant_id).delete()
        Menu.query.filter_by(tenant_id=tenant_id).delete()

        # 删除租户相关的业务数据
        from app.models.agents import Agent, Plan, Order, PaymentLog, ActivationCode, ActivationCodeBatch, Commission
        from app.models.user import User
        from app.models.recognition_record import RecognitionRecord

        Agent.query.filter_by(tenant_id=tenant_id).delete()
        Plan.query.filter_by(tenant_id=tenant_id).delete()
        Order.query.filter_by(tenant_id=tenant_id).delete()
        PaymentLog.query.filter_by(tenant_id=tenant_id).delete()
        ActivationCode.query.filter_by(tenant_id=tenant_id).delete()
        ActivationCodeBatch.query.filter_by(tenant_id=tenant_id).delete()
        Commission.query.filter_by(tenant_id=tenant_id).delete()
        User.query.filter_by(tenant_id=tenant_id).delete()
        RecognitionRecord.query.filter_by(tenant_id=tenant_id).delete()

        # 删除管理员日志（在记录删除日志之后）
        AdminLog.query.filter_by(tenant_id=tenant_id).delete()

        # 6. 最后删除租户
        db.session.delete(tenant)
        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'租户删除成功！',
            'data': {
                'deleted_admins': admin_count,
                # 'deleted_users': user_count,
                'tenant_name': tenant.name
            }
        })

    except Exception as e:
        db.session.rollback()
        logging.error(traceback.format_exc())
        return jsonify({'code': 1, 'message': f'删除失败: {str(e)}'}), 500


@admin_blueprint.route('/tenants/app', methods=['GET'])
def get_tenants_app_id():
    """获取租户 app_id"""
    tenant_id = request.args.get('tenant_id')

    if not tenant_id:
        return jsonify({'code': 1, 'message': 'tenant_id 不能为空'}), 400

    tenant = Tenant.query.get(tenant_id)
    if not tenant:
        return jsonify({'code': 1, 'message': '租户不存在'}), 404

    app_id = TenantConfigService.get_config(tenant_id, ConfigTypes.WECHAT_GZH, 'app_id')
    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': {'app_id': app_id}
    })


